#include <cstring>
#include <iostream>
#include <algorithm>
#include <vector>
#include <cstdio>
#include <cmath>

namespace std {
    class Read {
        public:
            template<typename T>
            inline Read & operator >> (T & x) {
                T sum = 0, opt = 1;
                char ch = getchar();
                while(!isdigit(ch)) opt = (ch == '-') ? -1 : 1, ch = getchar();
                while( isdigit(ch)) sum = (sum << 1) + (sum << 3) + (ch ^ 48), ch = getchar();
                x = sum * opt; return *this;
            }
    };
}
#define int long long
#define all(a) a.begin(), a.end()

using namespace std; Read fin;

const int INF = 0x3f3f3f3f3f3f3f3f;
const double eps = 1e-4;

int n, m, L;
double V;

struct CAR {
    int d, v, a;
};

vector<vector<int> > Erase;

void solve() {
    fin >> n >> m >> L;
    cin >> V;
    vector<CAR> cars(n);
    vector<int> limits(m);
    
    for (int i = 0; i < n; i ++ )
        fin >> cars[i].d >> cars[i].v >> cars[i].a;
    for (int j = 0; j < m; j ++ )
        fin >> limits[j];

    if (n <= 20) {
        vector<int> st(m, 0);

        for (int i = 0; i < n; i ++ ) {
            for (int j = 0; j < m; j ++ ) {
                double s = limits[j] - cars[i].d;
                double v = cars[i].v * cars[i].v + 2 * cars[i].a * s;
                if (v > 0 and s > 0) {
                    v = sqrt(v);
                    if (v - V > eps)
                        st[j] |= 1 << i;
                } else {
                    v = -1;
                }
                // printf("%lld %lld %lf %lf\n", i, j, v, V);
            }
        }
        int End = 0;
        for (int i = 0; i < m; i ++ )
            End |= st[i];
        
        int cnt = 0, t = End;

        while(t) {
            if (t & 1) cnt += 1;
            // printf("%d", (signed)t & 1);
            t >>= 1;
        }
        // puts("");
        cout << cnt << " ";

        int res = INF;

        for (int S = 0; S < 1 << m; S ++ ) {
            int temp = 0; cnt = 0;
            for (int i = 0; i < m; i ++ ) {
                if ((1 << i) & S) cnt ++ , temp |= st[i];
            }
            if (temp == End)
                res = min(res, cnt);
        }

        cout << m - res << endl;

    } else if (cars[0].a == 0) {
        int cnt = 0;
        sort(all(limits));
        for (int i = 0; i < n; i ++ )
            if (cars[i].d <= limits[m - 1] and cars[i].v > V)
                cnt += 1;
        
        cout << cnt << " " << m - (int)(cnt != 0) << endl;

    } else if (cars[0].a > 0) {
        int cnt = 0;
        sort(all(limits));
        for (int i = 0; i < n; i ++ )
            if (cars[i].d <= limits[m - 1]) {
                double s = limits[m - 1] - cars[i].d;
                double v = sqrt(cars[i].v * cars[i].v + 2 * cars[i].a * s);
                if (v - V > eps)
                    cnt += 1;
            }
        
        cout << cnt << " " << m - (int)(cnt != 0) << endl;

    } else {
        int cnt = 0;
        sort(all(limits));

        auto find_begin = [&](int x) -> int {
            int l = 0, r = m - 1;
            while(l < r) {
                int mid = l + r >> 1;
                int now = limits[mid];
                if (now >= x) r = mid;
                else l = mid + 1;
            }
            return r;
        };

        auto find_end = [&](int x) -> int {
            int l = 0, r = m - 1;
            while(l < r) {
                int mid = l + r + 1 >> 1;
                int now = limits[mid];
                if (x < now) r = mid - 1;
                else l = mid;  // now <= x
            }

            return l;
        };

        Erase.clear();
        Erase.resize(m + 1);

        vector<int> left(m);

        for (int i = 0; i < n; i ++ ) {
            // if (cars[i].d <= limits[0] and cars[i].v - V > eps) {
            //     double s = limits[0] - cars[i].d;
            //     double S = V * V - cars[i].v * cars[i].v;
            //     S = S / 2 / cars[i].a;
            //     if (S - s > eps)
            //         cnt += 1;
            // }
            // int F = find(cars[i].d);
            // if (cars[i].d > limits[m - 1]) continue;
            // if (F == m) continue;
            // if (cars[i].v - V < -eps) continue;

            // double s = limits[F] - cars[i].d;
            double S = 1.0 * V * V - cars[i].v * cars[i].v;
            S = S / (2.0 * cars[i].a);
            S = S + cars[i].d * 1.0;
            // cout << S << " " << s << endl;
            // if (S - s > eps)
            //     cnt += 1;

            int begin = find_begin(cars[i].d),
                end = find_end(S - eps);
            if (begin > end) continue;

            left[begin] += 1;
            // cout << i << endl;
            Erase[end + 1].push_back(-i);
            Erase[begin].push_back(i);
        }
        // puts("\n\n\n");

        for (int i = 1; i < m; i ++ )
            left[i] += left[i - 1];

        int tot = 0; cnt = 0;

        vector<bool> st(n, false), st2(n, false);

        auto check = [&](int x) -> bool {
            for (int i = 0; i < n; i ++ ) {
                if (st2[i] == true and st[i] == false)
                    return true;
            }
            return false;
        };

        for (int i = 0; i < m; i ++ ) {
            st2 = st;
            for (auto x : Erase[i]) {
                if (x > 0)
                    st[x] = true;
                else
                    st[-x] = false;
            }
            if (check(i)) {
                cnt ++ ;
                for (int j = 0; j < n; j ++ )
                    st[j] = false;
                for (auto x : Erase[i]) {
                    if (x > 0)
                        st[x] = true;
                    else
                        st[-x] = false;
                }
            }
        }
        // cout << tot << " ";

        cout << left[m - 1] << " " << m - cnt << endl;

        // cout << cnt << " " << m - (int)(cnt != 0) << endl;
    }
}

signed main() {
    freopen("detect.in", "r", stdin);
    freopen("detect.out", "w", stdout);
    int T = 0; fin >> T;

    while(T -- ) {
        solve();
    }
    return 0;
}